﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using ThreeByte.ActiveDeck.Data.UserResponse.Report;

namespace ThreeByte.ActiveDeck.Data {
    public class UserDataReportUtil {

        private static readonly XNamespace ns = Service.ServiceConfiguration.NAMESPACE;

        #region Users
        public static bool HasIndividualResponseData(string presentation) {
            ActiveDeckDataContext db = DataUtil.GetDataContext();

            var aUser = (from cs in db.CategorySubmissions
                         where cs.PresentationID == presentation
                         select new { cs.UserName })
                            .Union(from mc in db.MultipleChoices
                                   where mc.PresentationID == presentation
                                   select new { mc.UserName }).Union
                            (from sa in db.ShortAnswers
                             where sa.PresentationID == presentation
                             select new { sa.UserName }).FirstOrDefault();

            return (aUser != null);
        }

        public static List<IndividualResponseData> GetIndividualResponseData(string presentation) {
            ActiveDeckDataContext db = DataUtil.GetDataContext();

            List<IndividualResponseData> individualResponseData = new List<IndividualResponseData>();

            var users = (from cs in db.CategorySubmissions
                         where cs.PresentationID == presentation
                         select new { cs.UserName })
                            .Union(from mc in db.MultipleChoices
                                   where mc.PresentationID == presentation
                                   select new { mc.UserName }).Union
                            (from sa in db.ShortAnswers
                             where sa.PresentationID == presentation
                             select new { sa.UserName }).Distinct();

            foreach(var u in users) {
                individualResponseData.Add(new IndividualResponseData(u.UserName));
            }

            return individualResponseData;
        }
        #endregion

        #region MultipleChoice
        public static bool HasMultipleChoiceData(string presentation) {
            ActiveDeckDataContext db = DataUtil.GetDataContext();

            var anAnswer = (from a in db.MultipleChoices
                            where a.PresentationID == presentation
                            select a).FirstOrDefault();

            return (anAnswer != null);
        }

        public static List<MultipleChoiceIndividualData> GetMultipleChoiceIndividualData(string presentation, string userName) {
            ActiveDeckDataContext db = DataUtil.GetDataContext();

            List<MultipleChoiceIndividualData> multipleChoiceData = new List<MultipleChoiceIndividualData>();

            var answers = from a in db.MultipleChoices
                          where a.PresentationID == presentation
                          && a.UserName == userName
                          group a by new { a.Section, a.Page } into g
                          //orderby a.Timestamp descending
                          select new
                          {
                              Section = g.Key.Section,
                              Page = g.Key.Page,
                              Answer = g.OrderByDescending(p => p.Timestamp).First().Answer
                          };

            foreach(var a in answers) {
                MultipleChoiceIndividualData mcData = new MultipleChoiceIndividualData();
                mcData.Answer = a.Answer;
                mcData.Section = a.Section;
                mcData.Page = a.Page;
                mcData.TextAnswer = "";
                multipleChoiceData.Add(mcData);
            }

            return multipleChoiceData;

        }
        #endregion

        #region ShortAnswer
        public static bool HasShortAnswerData(string presentation) {
            ActiveDeckDataContext db = DataUtil.GetDataContext();

            var anAnswer = (from a in db.ShortAnswers
                            where a.PresentationID == presentation
                            select a).FirstOrDefault();

            return (anAnswer != null);
        }

        public static List<ShortAnswerIndividualData> GetShortAnswerIndividualData(string presentation, string userName) {
            ActiveDeckDataContext db = DataUtil.GetDataContext();

            List<ShortAnswerIndividualData> shortAnswerData = new List<ShortAnswerIndividualData>();

            var answers = from a in db.ShortAnswers
                          where a.PresentationID == presentation
                          && a.UserName == userName
                          group a by new { a.Section, a.Page } into g
                          select new
                          {
                              Section = g.Key.Section,
                              Page = g.Key.Page,
                              Answer = g.OrderByDescending(p => p.Timestamp).First().Answer
                          };

            foreach(var a in answers) {
                ShortAnswerIndividualData saData = new ShortAnswerIndividualData();
                saData.Section = a.Section;
                saData.Page = a.Page;
                saData.Answer = a.Answer;
                shortAnswerData.Add(saData);
            }

            return shortAnswerData;
        }
        #endregion

        #region Categories
        public static bool HasCategoriesAnswerData(string presentation) {
            ActiveDeckDataContext db = DataUtil.GetDataContext();

            var anAnswer = (from a in db.CategorySubmissions
                            where a.PresentationID == presentation
                            select a).FirstOrDefault();

            return (anAnswer != null);
        }

        public static List<CategoriesIndividualData> GetCategoriesIndividualData(string presentation, string userName) {
            ActiveDeckDataContext db = DataUtil.GetDataContext();

            List<CategoriesIndividualData> categoriesAnswerData = new List<CategoriesIndividualData>();

            var answers = from a in db.CategorySubmissions
                          join ci in db.CategoryItems
                          on a.ID equals ci.CategorySubmissionID
                          where a.PresentationID == presentation
                          && a.UserName == userName
                          select new { a, ci } into w
                          group w by new { w.a.Section, w.a.Page, w.ci.Item } into g
                          select new
                          {
                              Section = g.Key.Section,
                              Page = g.Key.Page,
                              Category = g.OrderByDescending(p => p.a.Timestamp).First().ci.Category,
                              Answer = g.Key.Item
                          };

            CategoriesIndividualData cData = new CategoriesIndividualData();
            foreach(var a in answers) {
                if(a.Section != cData.Section || a.Page != cData.Page) {
                    cData = new CategoriesIndividualData(a.Section, a.Page);
                    cData.CategoriesWords = new List<Tuple<CategoriesIndividualData.Word, CategoriesIndividualData.Category>>();
                    categoriesAnswerData.Add(cData);
                }
            }


            foreach(var a in answers) {
                Tuple<CategoriesIndividualData.Word, CategoriesIndividualData.Category> categoryWord = new Tuple<CategoriesIndividualData.Word, CategoriesIndividualData.Category>(new CategoriesIndividualData.Word(), new CategoriesIndividualData.Category());
                categoryWord.Item1.ID = a.Answer;
                categoryWord.Item2.ID = a.Category;

                categoriesAnswerData.Single(p => p.Page == a.Page
                    && p.Section == a.Section)
                    .CategoriesWords.Add(categoryWord);
            }

            return categoriesAnswerData;
        }
        #endregion
    }
}
